﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

using BankService.CallbackInterface;
using BankService.ServiceInterface;

namespace BankClient {

    [CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant,
        UseSynchronizationContext = false)]
    public class BankServiceProxy : IBankCallback, IDisposable {

        public delegate void NewTransferHandler(double amount, string message);
        public event NewTransferHandler NewTransfer;

        private IBankService bankService;
        private bool isLoggedIn;

        public BankServiceProxy() {
            this.isLoggedIn = false;

            NetTcpBinding binding = new NetTcpBinding();
            binding.Security.Mode = SecurityMode.None;
            EndpointAddress endpoint = new EndpointAddress(@"net.tcp://localhost:5588/BankService/Service");
            DuplexChannelFactory<IBankService> channelFactory = new DuplexChannelFactory<IBankService>(new InstanceContext(this), binding, endpoint);
            this.bankService = channelFactory.CreateChannel();
            ((ICommunicationObject)this.bankService).Open();
        }

        public LogInOutput LogIn(string username, string password) {
            if (this.isLoggedIn == false) {
                LogInOutput output = this.bankService.LogIn(new LogInInput(username, password));
                if (output != null)
                    this.isLoggedIn = true;
                return output;
            } else
                return null;
        }

        public void LogOut(string sessionId) {
            if (this.isLoggedIn == true) {
                this.bankService.LogOut(sessionId);
                this.isLoggedIn = false;
            }
        }

        public bool Register(string username, string address, string password) {
            return this.bankService.Register(new RegisterInput(username, address, password));
        }

        public bool Transfer(string sessionId, int to, double amount) {
            return this.bankService.Transfer(new TransferInput(sessionId, to, amount));
        }

        public void OnNewTransfer(Transfer transfer) {
            if (this.NewTransfer != null)
                this.NewTransfer(transfer.Amount,
                    transfer.Message);
        }

        public void Dispose() {
            ((ICommunicationObject)this.bankService).Close();
        }
    }
}
